import React, { useState, useEffect, useRef } from 'react';
import { Socket } from 'socket.io-client';
import './VoiceCall.css';

interface VoiceCallProps {
  isVisible: boolean;
  onClose: () => void;
  otherUser: {
    username: string;
    image: string;
  };
  currentUser: {
    username: string;
    image: string;
  };
  socket: Socket | null;
  isIncoming?: boolean;
  incomingOffer?: RTCSessionDescriptionInit;
  onCallStateChange?: (state: 'connected' | 'ended' | 'rejected') => void;
  callState?: 'idle' | 'calling' | 'connected' | 'ended';
  onCallEnded?: (duration: number) => void;
  isCallInitiator?: boolean;
}

const VoiceCall: React.FC<VoiceCallProps> = ({
  isVisible,
  onClose,
  otherUser,
  currentUser,
  socket,
  isIncoming: isIncomingCall = false,
  incomingOffer,
  onCallStateChange,
  callState: externalCallState,
  onCallEnded,
  isCallInitiator = false,
}) => {
  const [isIncoming, setIsIncoming] = useState(isIncomingCall);
  const [isCallActive, setIsCallActive] = useState(false);
  const [isMuted, setIsMuted] = useState(false);
  const [callDuration, setCallDuration] = useState(0);
  const [localStream, setLocalStream] = useState<MediaStream | null>(null);
  const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);

  const peerConnectionRef = useRef<RTCPeerConnection | null>(null);
  const localAudioRef = useRef<HTMLAudioElement>(null);
  const remoteAudioRef = useRef<HTMLAudioElement>(null);
  const durationIntervalRef = useRef<NodeJS.Timeout | null>(null);
  const startTimeRef = useRef<number>(0);

  // WebRTC配置
  const rtcConfig = {
    iceServers: [
      { urls: 'stun:stun.l.google.com:19302' },
      { urls: 'stun:stun1.l.google.com:19302' },
    ],
  };

  useEffect(() => {
    if (isVisible) {
      if (isIncomingCall && incomingOffer) {
        handleIncomingCall(incomingOffer);
      } else {
        initializeCall();
      }
    } else {
      cleanupCall();
    }
  }, [isVisible, isIncomingCall, incomingOffer]);

  // 监听外部通话状态变化
  useEffect(() => {
    if (externalCallState === 'connected' && !isCallActive) {
      console.log('外部状态更新：通话已接通');
      setIsCallActive(true);
      setIsIncoming(false);
    } else if (externalCallState === 'ended' && isCallActive) {
      console.log('外部状态更新：通话已结束');
      setIsCallActive(false);
      cleanupCall();
    }
  }, [externalCallState, isCallActive]);

  // 监听Socket消息，处理通话相关的消息
  useEffect(() => {
    if (!socket) return;

    const handleVoiceCallRequest = (data: any) => {
      console.log('收到语音通话请求:', data);
      if (data.fromUserId !== currentUser.username) {
        handleIncomingCall(data.offer);
      }
    };

    const handleVoiceCallAnswered = (data: any) => {
      console.log('收到语音通话应答:', data);
      if (peerConnectionRef.current && data.answer) {
        peerConnectionRef.current
          .setRemoteDescription(new RTCSessionDescription(data.answer))
          .then(() => {
            console.log('设置远程描述成功');
            setIsCallActive(true);
            setIsIncoming(false);
            onCallStateChange?.('connected');
          })
          .catch(error => {
            console.error('设置远程描述失败:', error);
          });
      }
    };

    const handleVoiceCallRejected = (data: any) => {
      console.log('对方拒绝了语音通话');
      onCallStateChange?.('rejected');
      onClose();
    };

    const handleVoiceCallEnded = (data: any) => {
      console.log('对方结束了语音通话');
      onCallStateChange?.('ended');
      onClose();
    };

    const handleIceCandidate = (data: any) => {
      console.log('收到ICE候选者:', data);
      if (peerConnectionRef.current && data.candidate) {
        peerConnectionRef.current
          .addIceCandidate(new RTCIceCandidate(data.candidate))
          .catch(error => {
            console.error('添加ICE候选者失败:', error);
          });
      }
    };

    const handleCallError = (data: any) => {
      console.error('通话错误:', data.message);
      alert(data.message || '通话失败');
      onClose();
    };

    socket.on('voice_call_request', handleVoiceCallRequest);
    socket.on('voice_call_answered', handleVoiceCallAnswered);
    socket.on('voice_call_rejected', handleVoiceCallRejected);
    socket.on('voice_call_ended', handleVoiceCallEnded);
    socket.on('ice_candidate', handleIceCandidate);
    socket.on('call_error', handleCallError);

    return () => {
      socket.off('voice_call_request', handleVoiceCallRequest);
      socket.off('voice_call_answered', handleVoiceCallAnswered);
      socket.off('voice_call_rejected', handleVoiceCallRejected);
      socket.off('voice_call_ended', handleVoiceCallEnded);
      socket.off('ice_candidate', handleIceCandidate);
      socket.off('call_error', handleCallError);
    };
  }, [socket, currentUser.username, onCallStateChange, onClose]);

  // 音频状态监控
  useEffect(() => {
    if (!isCallActive) return;

    const interval = setInterval(() => {
      if (remoteAudioRef.current) {
        console.log('音频状态监控:', {
          srcObject: remoteAudioRef.current.srcObject,
          paused: remoteAudioRef.current.paused,
          volume: remoteAudioRef.current.volume,
          muted: remoteAudioRef.current.muted,
          currentTime: remoteAudioRef.current.currentTime,
          duration: remoteAudioRef.current.duration,
          readyState: remoteAudioRef.current.readyState,
        });

        // 如果音频暂停了，尝试重新播放
        if (remoteAudioRef.current.paused && remoteAudioRef.current.srcObject) {
          console.log('检测到音频暂停，尝试重新播放');
          remoteAudioRef.current.play().catch(e => {
            console.error('重新播放音频失败:', e);
          });
        }
      }
    }, 5000); // 每5秒检查一次

    return () => clearInterval(interval);
  }, [isCallActive]);

  useEffect(() => {
    if (isCallActive) {
      startTimeRef.current = Date.now();
      durationIntervalRef.current = setInterval(() => {
        setCallDuration(Math.floor((Date.now() - startTimeRef.current) / 1000));
      }, 1000);
    } else {
      if (durationIntervalRef.current) {
        clearInterval(durationIntervalRef.current);
        durationIntervalRef.current = null;
      }
    }

    return () => {
      if (durationIntervalRef.current) {
        clearInterval(durationIntervalRef.current);
      }
    };
  }, [isCallActive]);

  const initializeCall = async () => {
    try {
      // 获取麦克风权限
      console.log('请求麦克风权限...');
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          autoGainControl: true,
        },
      });
      console.log('获取到本地音频流:', stream);
      setLocalStream(stream);

      if (localAudioRef.current) {
        localAudioRef.current.srcObject = stream;
      }

      // 创建RTCPeerConnection
      const pc = new RTCPeerConnection(rtcConfig);
      peerConnectionRef.current = pc;

      // 添加本地流
      stream.getTracks().forEach(track => {
        pc.addTrack(track, stream);
      });

      // 处理远程流
      pc.ontrack = event => {
        console.log('收到远程音频流:', event.streams[0]);
        setRemoteStream(event.streams[0]);
        if (remoteAudioRef.current) {
          remoteAudioRef.current.srcObject = event.streams[0];
          // 确保音频播放
          remoteAudioRef.current.play().catch(e => {
            console.error('播放远程音频失败:', e);
          });
        }
      };

      // 处理ICE候选者
      pc.onicecandidate = event => {
        if (event.candidate && socket) {
          socket.emit('ice_candidate', {
            fromUserId: currentUser.username,
            toUserId: otherUser.username,
            candidate: event.candidate,
          });
        }
      };

      // 发起通话
      await initiateCall();
    } catch (error) {
      console.error('初始化通话失败:', error);
      alert('无法访问麦克风，请检查权限设置');
      onClose();
    }
  };

  const initiateCall = async () => {
    if (!peerConnectionRef.current || !socket) return;

    try {
      const offer = await peerConnectionRef.current.createOffer();
      await peerConnectionRef.current.setLocalDescription(offer);

      // 发送通话邀请
      console.log('发起语音通话:', {
        fromUserId: currentUser.username,
        toUserId: otherUser.username,
      });
      socket.emit('voice_call_request', {
        fromUserId: currentUser.username,
        toUserId: otherUser.username,
        fromUserName: currentUser.username,
        fromUserImage: currentUser.image,
        offer: offer,
      });

      // 显示"正在呼叫..."状态
      console.log('正在呼叫...');

      // 设置超时，如果对方没有响应则关闭
      setTimeout(() => {
        if (!isCallActive && !isIncoming) {
          onClose();
        }
      }, 30000); // 30秒超时
    } catch (error) {
      console.error('创建通话邀请失败:', error);
      onClose();
    }
  };

  const handleIncomingCall = async (offer: RTCSessionDescriptionInit) => {
    try {
      // 获取麦克风权限
      console.log('请求麦克风权限...');
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          autoGainControl: true,
        },
      });
      console.log('获取到本地音频流:', stream);
      setLocalStream(stream);

      if (localAudioRef.current) {
        localAudioRef.current.srcObject = stream;
      }

      // 创建RTCPeerConnection
      const pc = new RTCPeerConnection(rtcConfig);
      peerConnectionRef.current = pc;

      // 监控连接状态
      pc.onconnectionstatechange = () => {
        console.log('WebRTC连接状态:', pc.connectionState);
      };

      pc.oniceconnectionstatechange = () => {
        console.log('ICE连接状态:', pc.iceConnectionState);
      };

      // 添加本地流
      stream.getTracks().forEach(track => {
        pc.addTrack(track, stream);
      });

      // 处理远程流
      pc.ontrack = event => {
        console.log('收到远程音频流:', event.streams[0]);
        setRemoteStream(event.streams[0]);
        if (remoteAudioRef.current) {
          remoteAudioRef.current.srcObject = event.streams[0];
          // 确保音频播放
          remoteAudioRef.current.play().catch(e => {
            console.error('播放远程音频失败:', e);
          });
        }
      };

      // 处理ICE候选者
      pc.onicecandidate = event => {
        if (event.candidate && socket) {
          socket.emit('ice_candidate', {
            fromUserId: currentUser.username,
            toUserId: otherUser.username,
            candidate: event.candidate,
          });
        }
      };

      // 设置远程描述（对方的offer）
      await pc.setRemoteDescription(new RTCSessionDescription(offer));

      setIsIncoming(true);
    } catch (error) {
      console.error('处理来电失败:', error);
      alert('无法访问麦克风，请检查权限设置');
      onClose();
    }
  };

  const acceptCall = async () => {
    if (!peerConnectionRef.current || !socket) return;

    try {
      const answer = await peerConnectionRef.current.createAnswer();
      await peerConnectionRef.current.setLocalDescription(answer);

      socket.emit('voice_call_answer', {
        fromUserId: currentUser.username,
        toUserId: otherUser.username,
        answer: answer,
      });

      setIsIncoming(false);
      setIsCallActive(true);
      console.log('通话已接通');
      onCallStateChange?.('connected');

      // 用户交互后强制播放音频
      if (remoteAudioRef.current && remoteAudioRef.current.srcObject) {
        console.log('用户接听后强制播放音频');
        remoteAudioRef.current.play().catch(e => {
          console.error('接听后播放音频失败:', e);
        });
      }
    } catch (error) {
      console.error('接受通话失败:', error);
      onCallStateChange?.('ended');
      onClose();
    }
  };

  const rejectCall = () => {
    if (socket) {
      socket.emit('voice_call_reject', {
        fromUserId: currentUser.username,
        toUserId: otherUser.username,
      });
    }

    // 保存通话时长，因为cleanupCall会重置callDuration
    const finalDuration = callDuration;
    const wasCallActive = isCallActive;

    // 只有通话发起者才发送通话时长消息
    if (wasCallActive && finalDuration > 0 && isCallInitiator) {
      console.log('通话发起者拒绝通话时发送通话时长消息，时长:', finalDuration);
      onCallEnded?.(finalDuration);
    }

    cleanupCall();
    onCallStateChange?.('rejected');
    onClose();
  };

  const endCall = () => {
    if (socket) {
      socket.emit('voice_call_end', {
        fromUserId: currentUser.username,
        toUserId: otherUser.username,
      });
    }

    // 保存通话时长，因为cleanupCall会重置callDuration
    const finalDuration = callDuration;
    const wasCallActive = isCallActive;

    // 只有通话发起者才发送通话时长消息
    if (wasCallActive && finalDuration > 0 && isCallInitiator) {
      console.log('通话发起者发送通话时长消息，时长:', finalDuration);
      onCallEnded?.(finalDuration);
    }

    cleanupCall();
    onCallStateChange?.('ended');
    onClose();
  };

  const toggleMute = () => {
    if (localStream) {
      const audioTrack = localStream.getAudioTracks()[0];
      if (audioTrack) {
        audioTrack.enabled = !audioTrack.enabled;
        setIsMuted(!audioTrack.enabled);
        console.log('麦克风状态:', audioTrack.enabled ? '已启用' : '已静音');
      }
    }
  };

  const cleanupCall = () => {
    if (localStream) {
      localStream.getTracks().forEach(track => track.stop());
      setLocalStream(null);
    }

    if (peerConnectionRef.current) {
      peerConnectionRef.current.close();
      peerConnectionRef.current = null;
    }

    setRemoteStream(null);
    setIsCallActive(false);
    setIsIncoming(false);
    setCallDuration(0);
  };

  const formatDuration = (seconds: number) => {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
  };

  if (!isVisible) return null;

  return (
    <div className="voice-call-overlay">
      <div
        className={`voice-call-container ${isIncoming ? 'incoming-call' : ''} ${isCallActive ? 'call-active' : ''} ${!isIncoming && !isCallActive ? 'calling' : ''}`}
      >
        {/* 用户信息 */}
        <div className="user-info">
          <div className="user-avatar">
            <img
              src={otherUser.image}
              alt={otherUser.username}
              className="w-full h-full object-cover"
              onError={e => {
                e.currentTarget.src = `https://api.dicebear.com/7.x/avataaars/svg?seed=${otherUser.username}`;
              }}
            />
          </div>
          <h3 className="user-name">{otherUser.username}</h3>
          {isCallActive && (
            <p className="call-duration">{formatDuration(callDuration)}</p>
          )}
          {isIncoming && !isCallActive && (
            <p className="call-status">来电...</p>
          )}
          {!isIncoming && !isCallActive && (
            <p className="call-status">正在呼叫...</p>
          )}
          {isCallActive && (
            <div className="call-info">
              <p>
                <span>本地音频</span>
                <span className="status-icon">{localStream ? '✓' : '✗'}</span>
              </p>
              <p>
                <span>远程音频</span>
                <span className="status-icon">{remoteStream ? '✓' : '✗'}</span>
              </p>
              <p>
                <span>连接状态</span>
                <span className="status-icon">
                  {peerConnectionRef.current?.connectionState || '未知'}
                </span>
              </p>
            </div>
          )}
        </div>

        {/* 通话控制按钮 */}
        <div className="controls">
          {isIncoming && !isCallActive ? (
            // 来电界面 - 接听/拒绝
            <>
              <button
                onClick={acceptCall}
                className="control-button accept-button"
                title="接听"
              >
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"
                  />
                </svg>
              </button>
              <button
                onClick={rejectCall}
                className="control-button reject-button"
                title="拒绝"
              >
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M6 18L18 6M6 6l12 12"
                  />
                </svg>
              </button>
            </>
          ) : isCallActive ? (
            // 通话中界面 - 静音/挂断
            <>
              <button
                onClick={toggleMute}
                className={`control-button mute-button ${isMuted ? 'muted' : ''}`}
                title={isMuted ? '取消静音' : '静音'}
              >
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  {isMuted ? (
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z"
                    />
                  ) : (
                    <path
                      strokeLinecap="round"
                      strokeLinejoin="round"
                      strokeWidth={2}
                      d="M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z"
                    />
                  )}
                </svg>
              </button>
              <button
                onClick={endCall}
                className="control-button hangup-button"
                title="挂断"
              >
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M16 8l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2M5 3a2 2 0 00-2 2v1c0 8.284 6.716 15 15 15h1a2 2 0 002-2v-3.28a1 1 0 00-.684-.948l-4.493-1.498a1 1 0 00-1.21.502l-1.13 2.257a11.042 11.042 0 01-5.516-5.517l2.257-1.128a1 1 0 00.502-1.21L9.228 3.683A1 1 0 008.28 2.99L5 3z"
                  />
                </svg>
              </button>
            </>
          ) : (
            // 正在呼叫界面 - 挂断按钮
            <button
              onClick={endCall}
              className="control-button hangup-button"
              title="挂断"
            >
              <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M16 8l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2M5 3a2 2 0 00-2 2v1c0 8.284 6.716 15 15 15h1a2 2 0 002-2v-3.28a1 1 0 00-.684-.948l-4.493-1.498a1 1 0 00-1.21.502l-1.13 2.257a11.042 11.042 0 01-5.516-5.517l2.257-1.128a1 1 0 00.502-1.21L9.228 3.683A1 1 0 008.28 2.99L5 3z"
                />
              </svg>
            </button>
          )}
        </div>

        {/* 隐藏的音频元素 */}
        <div className="audio-elements">
          <audio ref={localAudioRef} autoPlay muted />
          <audio
            ref={remoteAudioRef}
            autoPlay
            controls={false}
            onLoadedMetadata={() => {
              console.log('远程音频元数据已加载');
              if (remoteAudioRef.current) {
                remoteAudioRef.current.play().catch(e => {
                  console.error('自动播放远程音频失败:', e);
                });
              }
            }}
            onCanPlay={() => {
              console.log('远程音频可以播放');
            }}
            onError={e => {
              console.error('远程音频播放错误:', e);
            }}
          />
        </div>
      </div>
    </div>
  );
};

export default VoiceCall;
